package com.sl.ms.dispatch.mq;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.sl.ms.dispatch.dto.DispatchMsgDTO;
import com.sl.transport.common.constant.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;

/**
 * 对于待调度运单消息的处理
 */

@Slf4j
@Component
public class TransportOrderDispatchMQListener {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 处理消息，合并运单到Redis队列
     *
     * @param msg
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = Constants.MQ.Queues.DISPATCH_MERGE_TRANSPORT_ORDER),
            exchange = @Exchange(name = Constants.MQ.Exchanges.TRANSPORT_ORDER_DELAYED, type = ExchangeTypes.TOPIC, delayed = Constants.MQ.DELAYED),
            key = Constants.MQ.RoutingKeys.JOIN_DISPATCH
    ))
    public void listenDispatchMsg(String msg) {
        // {"transportOrderId":"SL1000000000560","currentAgencyId":100280,"nextAgencyId":90001,"totalWeight":3.5,"totalVolume":2.1,"created":1652337676330}
        log.info("接收到新运单的消息 >>> msg = {}", msg);
        // 1.将消息转为 DispatchMsgDTO对象
        DispatchMsgDTO dispatchMsgDTO = JSONUtil.toBean(msg, DispatchMsgDTO.class);

        // 2.获取 当前网点id  下一站网点 id  运单id

        String transportOrderId = dispatchMsgDTO.getTransportOrderId();
        Long currentAgencyId = dispatchMsgDTO.getCurrentAgencyId();
        Long nextAgencyId = dispatchMsgDTO.getNextAgencyId();

        // 3. 获取SET集合对应的key: 前缀_当前网点ID_下一点网点ID

        String setRedisKey = getSetRedisKey(currentAgencyId, nextAgencyId);

        // 4.判断在set集合中是否存在  改运单ID isMember : boolean
        // 进行幂等性的校验
        Boolean member = stringRedisTemplate.opsForSet().isMember(setRedisKey, transportOrderId);

        if (Boolean.TRUE.equals(member)) {
            return;
        }


        // 5.

        String listRedisKey = getListRedisKey(currentAgencyId, nextAgencyId);

        // 转为json
        String value = JSONUtil.toJsonStr(MapUtil.builder()
                .put("transportOrderId", transportOrderId)
                .put("totalVolume", dispatchMsgDTO.getTotalVolume())
                .put("totalWeight", dispatchMsgDTO.getTotalWeight())
                .put("created", dispatchMsgDTO.getCreated())
                .build());
        //TODO 待实现
        //存储到redis
        this.stringRedisTemplate.opsForList().leftPush(listRedisKey, value);
        // 去重处理  转入运单id就可以了
        this.stringRedisTemplate.opsForSet().add(setRedisKey, transportOrderId);
    }

    /**
     * 生成redis前缀List类型
     *
     * @param startId
     * @param endId
     * @return
     */
    public String getListRedisKey(Long startId, Long endId) {
        return StrUtil.format("DISPATCH_LIST_{}_{}", startId, endId);
    }

    /**
     * 生成redis前缀 set类型
     *
     * @param startId
     * @param endId
     * @return
     */
    public String getSetRedisKey(Long startId, Long endId) {
        return StrUtil.format("DISPATCH_SET_{}_{}", startId, endId);
    }

}
